;(function($){
	
	$.history = (function(){
		var _iframe = null;

    	var _storageField = null;

    	var _initialized = false;

    	var _storageFieldReady = false;

    	var _bhmReady = false;
    	
    	/**
    	 * initialState : 初始状态
    	 * currentState ：当前状态
    	 * onStateChange ：响应状态改变的回调函数
    	 */
    	var _stateInfo = {};
    	
    	function _trim( str ) {
        	return str.replace( /^\s*(\S*(\s+\S+)*)\s*$/, "$1" );
    	}

    	function _getHash() {
        	var href = top.location.href;
        	var i = href.indexOf( "#" );
        	return i >= 0 ? href.substr( i + 1 ) : null;
    	}
    	
    	function _storeState() {
    		_storageField.value = _stateInfo.initialState + "|" + _stateInfo.currentState;
        }
    	
    	function _handleFQStateChange( fqstate ) {
    		
    		if(!fqstate){
    			if(!!_stateInfo){
    				_stateInfo.onStateChange(unescape(_stateInfo.currentState));
    			}
    			return;
    		}
    		
    	}
    	
    	/**
     	 * Update the IFrame with our new state.
         *
         * @method _updateIFrame
         * @private
         * @return {boolean} true if successful. false otherwise.
         */
         function _updateIFrame (fqstate) {
            var html, doc;
            html = '<html><body><div id="state">' + fqstate + '</div></body></html>';
            try {
                doc = _histFrame.contentWindow.document;
                doc.open();
                doc.write(html);
                doc.close();
                return true;
            } catch (e) {
                return false;
            }
    	 }
    	 
    	 /**
     	  * Periodically checks whether our internal IFrame is ready to be used.
     	  *
     	  * @method _checkIframeLoaded
     	  * @private
     	  */
    	  function _checkIframeLoaded() {
          	var doc, elem, fqstate, hash;
          	if (!_histFrame.contentWindow || !_histFrame.contentWindow.document) {
            	// Check again in 10 msec...
            	setTimeout(_checkIframeLoaded, 10);
            	return;
        	}
        	// Start the thread that will have the responsibility to
        	// periodically check whether a navigate operation has been
        	// requested on the main window. This will happen when
        	// YAHOO.util.History.navigate has been called or after
        	// the user has hit the back/forward button.

        	doc = _histFrame.contentWindow.document;
        	elem = doc.getElementById("state");
        	// We must use innerText, and not innerHTML because our string contains
        	// the "&" character (which would end up being escaped as "&amp;") and
        	// the string comparison would fail...
        	fqstate = elem ? elem.innerText : null;
       	 	hash = _getHash();
        	setInterval(function () {
            	var newfqstate, newHash, historyLength;
            	doc = _histFrame.contentWindow.document;
            	elem = doc.getElementById("state");
            	// See my comment above about using innerText instead of innerHTML...
            	newfqstate = elem ? elem.innerText : null;
            	newHash = _getHash();

            	if (newfqstate !== fqstate) {

                	fqstate = newfqstate;
                	_handleFQStateChange(fqstate);

                	if (!fqstate) {
                    	newHash = _initialState;
                	} else {
                    	newHash = fqstate;
                	}

                	// Allow the state to be bookmarked by setting the top window's
                	// URL fragment identifier. Note that here, we are on IE, and
                	// IE does not touch the browser history when setting the hash
                	// (unlike all the other browsers). I used to write:
                	//     top.location.replace( "#" + hash );
                	// but this had a side effect when the page was not the top frame.
                	top.location.hash = newHash;
                	hash = newHash;

               	    _storeState();

                } else if (newHash !== hash) {

                	// The hash has changed. The user might have clicked on a link,
                	// or modified the URL directly, or opened the same application
                	// bookmarked in a specific state using a bookmark. However, we
                	// know the hash change was not caused by a hit on the back or
                	// forward buttons, or by a call to navigate() (because it would
                	// have been handled above) We must handle these cases, which is
                	// why we also need to keep track of hash changes on IE!

                	// Note that IE6 has some major issues with this kind of user
                	// interaction (the history stack gets completely messed up)
                	// but it seems to work fine on IE7.

                	hash = newHash;

                	// Now, store a new history entry. The following will cause the
                	// code above to execute, doing all the dirty work for us...
                	_updateIFrame(newHash);
            	}
        	}, 50);

        	_initialized = true;
        	$().trigger('historyload');
    	}
		
	})();
	
})(jQuery)